package com.example.pipibee.service.imp;

import com.example.pipibee.dao.repository.DoctorRepository;
import com.example.pipibee.pojo.param.*;
import com.example.pipibee.pojo.vo.*;
import com.example.pipibee.service.DoctorService;
import com.example.pipibee.web.ServiceCode;
import com.example.pipibee.web.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

/**
 * 医生端_业务层
 */
@Slf4j
@Service
public class DoctorServiceImp implements DoctorService {

    @Autowired
    DoctorRepository doctorRepository;

    @Override
    public void addNewMrin(DoctorInsertParam doctorInsertParam) {
        log.debug("开始处理【插入_住院病案_主表】的业务,参数{}", doctorInsertParam);
        int rows = doctorRepository.insertMrin(doctorInsertParam);
        if (rows != 1) {
            String message = "插入_住院病案_主表...失败，服务器忙，请稍后再尝试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_INSERT, message);
        }
    }

    @Override
    public void addNewDia(DoctorDiaInsertParam doctorDiaInsertParam) {
        log.debug("开始处理【插入_住院病案_诊断表】的业务,参数{}", doctorDiaInsertParam);


        //判断是否为主要诊断(主要诊断唯一)
        doctorDiaInsertParam.setMrInId(doctorRepository.selectIdByMrNum(doctorDiaInsertParam.getMrNum()));
        Integer diaType = doctorDiaInsertParam.getDiaType();    //该诊断类型
        String mrInId = doctorDiaInsertParam.getMrInId();       //该诊断住院病案ID
        if (1 == diaType) {
            int rows = doctorRepository.diaLooker(mrInId);
            if (rows != 0) {
                String message = "插入_住院病案_诊断表...失败，主要诊断不唯一！";
                log.warn(message);
                throw new ServiceException(ServiceCode.ERROR_INSERT, message);
            }
        }

        //根据ID查询住院病案是否存在
        int rows1 = doctorRepository.mrinLooker(mrInId);
        if (rows1 != 1) {
            String message = "插入_住院病案_诊断表...失败，住院病案ID异常！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_INSERT, message);
        }

        //正常压入
        int rows2 = doctorRepository.insertDia(doctorDiaInsertParam);
        if (rows2 != 1) {
            String message = "插入_住院病案_诊断表...失败，服务器忙，请稍后再尝试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_INSERT, message);
        }
    }

    @Override
    public void addNewSur(DoctorSurInsertParam doctorSurInsertParam) {
        log.debug("开始处理【插入_住院病案_手术表】的业务,参数{}", doctorSurInsertParam);

        //判断是否为主要手术
        doctorSurInsertParam.setMrInId(doctorRepository.selectIdByMrNum(doctorSurInsertParam.getMrNum()));
        Integer surType = doctorSurInsertParam.getSurType();    //该手术类型
        String mrInId = doctorSurInsertParam.getMrInId();       //该手术住院病案ID
        if (1 == surType) {
            int rows = doctorRepository.surLooker(mrInId);
            if (rows != 0) {
                String message = "插入_住院病案_手术表...失败，主要手术不唯一！";
                log.warn(message);
                throw new ServiceException(ServiceCode.ERROR_INSERT, message);
            }
        }

        //根据ID查询住院病案是否存在
        int rows1 = doctorRepository.mrinLooker(mrInId);
        if (rows1 != 1) {
            String message = "插入_住院病案_手术表...失败，住院病案ID异常！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_INSERT, message);
        }

        //正常压入
        int rows2 = doctorRepository.insertSur(doctorSurInsertParam);
        if (rows2 != 1) {
            String message = "插入_住院病案_手术表...失败，服务器忙，请稍后再尝试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_INSERT, message);
        }
    }

    @Override
    public void deleteDia(DoctorDiaDeleteParam doctorDiaDeleteParam) {
        log.debug("开始处理【批量删除_住院病案_诊断表】的业务,参数{}", doctorDiaDeleteParam);
        doctorDiaDeleteParam.setMrInId(doctorRepository.selectIdByMrNum(doctorDiaDeleteParam.getMrNum()));
        doctorRepository.deleteDia(doctorDiaDeleteParam);
    }

    @Override
    public void deleteSur(DoctorSurDeleteParam doctorSurDeleteParam) {
        log.debug("开始处理【批量删除_住院病案_手术表】的业务,参数{}", doctorSurDeleteParam);
        doctorSurDeleteParam.setMrInId(doctorRepository.selectIdByMrNum(doctorSurDeleteParam.getMrNum()));
        doctorRepository.deleteSur(doctorSurDeleteParam);
    }

    @Override
    public void deleteAllMrin(DoctorDeleteAllMrinParam doctorDeleteAllMrinParam) {
        log.debug("开始处理【ALL删除_住院病案_主表】的业务,参数{}", doctorDeleteAllMrinParam);

        List<Long> mrNums = doctorDeleteAllMrinParam.getMrNums();
        for (Long mrNum : mrNums) {
            String mrInId = doctorRepository.selectIdByMrNum(mrNum);
            doctorDeleteAllMrinParam.setMrInId(mrInId);
            DoctorDeleteAllDiaParam doctorDeleteAllDiaParam = new DoctorDeleteAllDiaParam(mrInId);
            DoctorDeleteAllSurParam doctorDeleteAllSurParam = new DoctorDeleteAllSurParam(mrInId);

            doctorRepository.deleteAllMrin(doctorDeleteAllMrinParam);
            doctorRepository.deleteAllDia(doctorDeleteAllDiaParam);
            doctorRepository.deleteAllSur(doctorDeleteAllSurParam);
        }
    }

    @Override
    public void updateMrin(DoctorUpdateMrinParam doctorUpdateMrinParam) {
        log.debug("开始处理【修改_住院病案_主表】的业务,参数{}", doctorUpdateMrinParam);
        doctorRepository.updateMrin(doctorUpdateMrinParam);
    }

    @Override
    public void updateDia(DoctorDiaUpdateParam doctorDiaUpdateParam) {
        log.debug("开始处理【修改_诊断表】的业务,参数{}", doctorDiaUpdateParam);
        doctorRepository.updateDia(doctorDiaUpdateParam);
    }

    @Override
    public void updateSur(DoctorSurUpdateParam doctorSurUpdateParam) {
        log.debug("开始处理【修改_手术表】的业务,参数{}", doctorSurUpdateParam);
        doctorRepository.updateSur(doctorSurUpdateParam);
    }

    @Override
    public void discharge(DoctorDischargeParam doctorDischargeParam) {
        log.debug("开始处理【批量出院】的业务,参数{}", doctorDischargeParam);
        doctorRepository.discharge(doctorDischargeParam);
    }

    @Override
    public void submit(DoctorSubmitParam doctorSubmitParam) {
        log.debug("开始处理【医生端_批量提交】的业务,参数{}", doctorSubmitParam);

        List<Long> mrNums = doctorSubmitParam.getMrNums();
        for (Long mrNum : mrNums) {
            int approvalStatus = doctorRepository.lookAppByMrNum(mrNum);
            if (1 == approvalStatus || 3 == approvalStatus) {
                DoctorSubmitParam2 doctorSubmitParam2 = new DoctorSubmitParam2(mrNum, 2);
                doctorRepository.submit(doctorSubmitParam2);
            } else if (4 == approvalStatus) {
                DoctorSubmitParam2 doctorSubmitParam2 = new DoctorSubmitParam2(mrNum, 5);
                doctorRepository.submit(doctorSubmitParam2);
            }

        }

    }

    @Override
    public void approval(DoctorApprovalParam doctorApprovalParam) {
        log.debug("开始处理【病案室_批量审批】的业务,参数{}", doctorApprovalParam);

        List<Long> mrNums = doctorApprovalParam.getMrNums();
        for (Long mrNum : mrNums) {
            int approval = doctorApprovalParam.getApproval();
            if (1 == approval) {
                DoctorApprovalParam2 doctorApprovalParam2 = new DoctorApprovalParam2(mrNum, 4);
                doctorRepository.approval(doctorApprovalParam2);
            } else if (2 == approval) {
                DoctorApprovalParam2 doctorApprovalParam2 = new DoctorApprovalParam2(mrNum, 3);
                doctorRepository.approval(doctorApprovalParam2);
            }
        }
    }

    @Override
    public DoctorSurUpdateSelectVO updateSurSelect(DoctorSurUpdateSelectParam doctorSurUpdateSelectParam) {
        log.debug("开始处理【查询填充_手术表】的业务,参数{}", doctorSurUpdateSelectParam);
        return doctorRepository.updateSurSelect(doctorSurUpdateSelectParam);
    }

    @Override
    public DoctorDiaUpdateSelectVO updateDiaSelect(DoctorDiaUpdateSelectParam doctorDiaUpdateSelectParam) {
        log.debug("开始处理【查询填充_诊断表】的业务,参数{}", doctorDiaUpdateSelectParam);
        return doctorRepository.updateDiaSelect(doctorDiaUpdateSelectParam);
    }

    @Override
    public PageBean selectList(DoctorListSelectParam doctorListSelectParam) {
        log.debug("开始处理【查询_住院病案_简略列表】的业务,参数{}", doctorListSelectParam);

        Long total = doctorRepository.count(doctorListSelectParam);
        List<DoctorListSelectVO> rows = doctorRepository.list(doctorListSelectParam);
        PageBean pageBean = new PageBean(total, rows);

        return pageBean;
    }

    @Override
    public DoctorSelectMrinVO selectMrin(DoctorDataSelectParam doctorDataSelectParam) {
        log.debug("开始处理【查询_住院病案_主表】的业务,参数{}", doctorDataSelectParam);
        String id = doctorRepository.selectIdByMrNum(doctorDataSelectParam.getMrNum());
        return doctorRepository.selectMrinById(id);
    }

    @Override
    public List<DoctorSelectDiaVO> selectDia(DoctorDataSelectParam doctorDataSelectParam) {
        log.debug("开始处理【查询_住院病案_诊断表】的业务,参数{}", doctorDataSelectParam);
        String id = doctorRepository.selectIdByMrNum(doctorDataSelectParam.getMrNum());
        return doctorRepository.selectDiaById(id);
    }

    @Override
    public List<DoctorSelectSurVO> selectSur(DoctorDataSelectParam doctorDataSelectParam) {
        log.debug("开始处理【查询_住院病案_手术表】的业务,参数{}", doctorDataSelectParam);
        String id = doctorRepository.selectIdByMrNum(doctorDataSelectParam.getMrNum());
        return doctorRepository.selectSurById(id);
    }

    @Override
    public void export(DoctorListSelectParam doctorListSelectParam, HttpServletResponse response) {
        log.debug("开始处理【住院病案_简略列表_Excel导出】的业务,参数{},{}", doctorListSelectParam, response);

        //获取详细数据和详细数据总条数
        List<DoctorListSelectVO> datas = doctorRepository.list(doctorListSelectParam);
        int datasLong = datas.size();

        //获得Excel模板
        InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("template/病案管理系统_病案数据导出_模板.xlsx");

        try {

            //基于Excel模板创建一个新的Excel表格对象
            XSSFWorkbook excel = new XSSFWorkbook(inputStream);

            //获得Excel文件中的一个Sheet页
            XSSFSheet sheet = excel.getSheet("Sheet1");

            //循环压入数据
            for (int i = 0; i < datasLong; i++) {

                DoctorListSelectVO data = datas.get(i);     //拿到当前循环的单条数据

                XSSFRow row = sheet.getRow(i + 1);  //拿到当前的行（跳过模板表头所占的一行）
                if (null == row) {                          //如果该行为空,则创建
                    row = sheet.createRow(i + 1);
                }

                //拿到列对象
                XSSFCell c1 = row.getCell(0);
                XSSFCell c2 = row.getCell(1);
                XSSFCell c3 = row.getCell(2);
                XSSFCell c4 = row.getCell(3);
                XSSFCell c5 = row.getCell(4);
                XSSFCell c6 = row.getCell(5);
                XSSFCell c7 = row.getCell(6);
                XSSFCell c8 = row.getCell(7);
                XSSFCell c9 = row.getCell(8);

                //如果列为空,则创建
                if (null == c1) {
                    c1 = row.createCell(0);
                }
                if (null == c2) {
                    c2 = row.createCell(1);
                }
                if (null == c3) {
                    c3 = row.createCell(2);
                }
                if (null == c4) {
                    c4 = row.createCell(3);
                }
                if (null == c5) {
                    c5 = row.createCell(4);
                }
                if (null == c6) {
                    c6 = row.createCell(5);
                }
                if (null == c7) {
                    c7 = row.createCell(6);
                }
                if (null == c8) {
                    c8 = row.createCell(7);
                }
                if (null == c9) {
                    c9 = row.createCell(8);
                }

                //压入数据
                c1.setCellValue(data.getMrNumber());        //在第1列写入病案号
                c2.setCellValue(data.getName());            //在第2列写入患者姓名
                c3.setCellValue(data.getGender());          //在第3列写入患者性别
                c4.setCellValue(data.getIdCard());          //在第4列写入患者身份证号
                c5.setCellValue(data.getDischargeMethod()); //在第5列写入离院方式
                c6.setCellValue(data.getApprovalStatus());  //在第6列写入病案状态
                c7.setCellValue(data.getDoctor());          //在第7列写入住院医师
                c8.setCellValue(data.getGmtCreate());       //在第8列写入数据创建时间
                c9.setCellValue(data.getGmtModified());     //在第9列写入最后更新时间


            }

            //通过输出流将文件下载到客户端浏览器中
            ServletOutputStream out = response.getOutputStream();
            excel.write(out);

            //关闭资源
            out.flush();
            out.close();
            excel.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}






















